#####################################################################
# File:         CheckBox.py
# Product:      KnowledgeEngine
#
# Copyright:    Copyright (c) 2001, Faulkner Ltd.
# Author:       Brian Oliver + Tom Cameron
#
# Description:  This file defines the CheckBox class, a simple
#               component to represent a boolean selection 
#               in an assessment 
#
#               TC: 03/08/2002 - I have extended this component to be
#               a complete 'True/False' scorable component. It can
#               now render is several different forms and has the
#               notion of a score and correctness added. But for
#               backward compatibility it is still called the
#               CheckBox.py class file
#
# See Also:     Component, Model, Section
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.KnowledgeEngineCore import *
from Products.KnowledgeEngine.BooleanComponent import BooleanComponent, BooleanComponentInfo
from Products.KnowledgeEngine.Components.Section.Section import Section
from Products.KnowledgeEngine.Library.Library import Library
from Products.KnowledgeEngine.Scorable import *
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## CheckBoxInfo Class Definition
class CheckBoxInfo(BooleanComponentInfo, ScorableInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """

    #---------------------------------------------------------------#

    def getClassName(self):
        """
            Return the class name
        """
        
        return 'CheckBox'

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "True/False"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "chk"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('www/icon.gif', globals())

    #---------------------------------------------------------------#

    def isInstanceOf(self, className):
        """
            Returns if the class is an instance of the specified
            className, or implements the interface specified 
            by the className
        """

        return ScorableInfo.isInstanceOf(self,className) or BooleanComponentInfo.isInstanceOf(self, className)
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        BooleanComponentInfo.onConfigureProperties(self)
        ScorableInfo.onConfigureProperties(self)
        
        #add the 'displayFormat' property        
        self.addPropertyDefinition(PropertyDefinition(identity="displayFormat", displayName="Display As", description="How values are to be selected/displayed?", propertyType=pt_STRING, propertyFormat=pf_NATIVE, hasEnumeratedValues=true, enumeratedValuesList=["Yes/No","True/False","On/Off","CheckBox"], defaultValue="CheckBox"))

        #add the 'scoreTrue' property        
        self.addPropertyDefinition(PropertyDefinition(identity="scoreTrue", displayName="Score When Selected", description="The score for the component when Selected/On/Yes/Checked in an assessment", defaultValue=1.0, propertyType=pt_FLOAT, propertyFormat=pf_NATIVE, propertyStructure=ps_ATOMIC))        

        #add the 'scoreFalse' property        
        self.addPropertyDefinition(PropertyDefinition(identity="scoreFalse", displayName="Score When Unselected", description="The score for the component when Unelected/Off/No/Unchecked in an assessment", defaultValue=0.0, propertyType=pt_FLOAT, propertyFormat=pf_NATIVE, propertyStructure=ps_ATOMIC))        
            
    #---------------------------------------------------------------#

#####################################################################
## CheckBox Class Definition
class CheckBox(BooleanComponent, Scorable):
    """
        Defines a a simple component to represent a boolean selection 
        in an assessment
    """

    #---------------------------------------------------------------#

    #TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = CheckBoxInfo()
    
    #---------------------------------------------------------------#

    # Default Values for backward compatibility     
    displayList = ["Yes/No","True/False","On/Off","CheckBox"]
    displayFormat = "CheckBox"
    scoreTrue = 1.0
    scoreFalse = 0.0
    
    #---------------------------------------------------------------#

    # DTML Methods
    index_html = DTMLFile('dtml/index_html', globals())
    simplereport_html = DTMLFile('dtml/simplereport_html', globals())
    scoredreport_html = DTMLFile('dtml/scoredreport_html', globals())
    scored360report_html = DTMLFile('dtml/scored360report_html', globals())
    csv360report_html = DTMLFile('dtml/csv360report_html', globals())
    groupedreport_html = DTMLFile('dtml/groupedreport_html', globals())    

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the CheckBox"        

        BooleanComponent.__init__(self, id, identity)
        
    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """
        
        #perform BooleanComponent.onAfterInstanciation processing
        BooleanComponent.onAfterInstanciation(self)
        
        ###print "DEBUG: CheckBoxComponent.onAfterInstanciation: Completed"

    #---------------------------------------------------------------#

    def getDisplayFormat(self):
        "Return the display format of this object"
        
        return self.displayFormat

    #---------------------------------------------------------------#
        
    def getScore(self, assessmentCache, componentContext = None):
        """
            Evaluates the unweighted score of the component..

            Typically called by Scorable.getScore() to retrieve
            score. Or Scorable.getScore()*Scorable.getWeighting()

            NOTE: Must return a real number
        """

        #get the identity
        identity = self.getIdentity(componentContext)

        #get the stored state
        state = assessmentCache.getState(identity)

        #evaluate and return the score
        if state == true:
            return self.scoreTrue           
        else:
            return self.scoreFalse  
        
    #---------------------------------------------------------------#
        
    def getMaxScore(self):
        """
            Evaluates the maximum potential score
        """

        #evaluate and return the score
        return max([self.scoreTrue,self.scoreFalse])
        
    #---------------------------------------------------------------#


#####################################################################
## Class Initialisation

# Register Class Information with the Knowledge Engine
registerGenericObjectClass(CheckBox)

#####################################################################
